package com.example.elderlycare.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.elderlycare.config.ZhenziSmsConfig;
import com.example.elderlycare.controller.entity.UserRequestBody;
import com.example.elderlycare.dao.entity.SmsLog;
import com.example.elderlycare.dao.entity.User;
import com.example.elderlycare.exception.AuthCodeExpiredException;
import com.example.elderlycare.exception.AuthCodeNotMatchException;
import com.example.elderlycare.exception.NoBalanceException;
import com.example.elderlycare.service.SmsService;
import com.example.elderlycare.service.UserService;
import com.example.elderlycare.service.entity.QueryListResponseBody;
import com.example.elderlycare.service.entity.SmsResponseBody;
import com.example.elderlycare.service.entity.UserItem;
import com.example.elderlycare.utils.CurrentUser;
import com.example.elderlycare.utils.PasswordMD5;
import com.example.elderlycare.utils.Result;
import com.example.elderlycare.utils.ResultEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.Random;

@RestController
@Slf4j
@RequestMapping("/user")
public class UserController {

    @Resource
    UserService userService;

    @Resource
    SmsService smsService;

    @Resource
    ZhenziSmsConfig zhenziSmsConfig;

    /**
     * 查询用户列表
     *
     * @param id       用户记录id
     * @param username 用户名
     * @param nickname 用户昵称
     * @param phone    手机号码
     * @param pageSize 页大小
     * @param current  当前页
     * @return QueryListResponseBody<UserItem>
     */
    @GetMapping
    public Result<QueryListResponseBody<UserItem>> queryUserList(
            @RequestParam(value = "id", required = false) String id,
            @RequestParam(value = "username", required = false) String username,
            @RequestParam(value = "nickname", required = false) String nickname,
            @RequestParam(value = "phone", required = false) String phone,
            @RequestParam(defaultValue = "10", value = "pageSize") int pageSize,
            @RequestParam(defaultValue = "1", value = "current") int current
    ) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(id != null && !"".equals(id), "id", id)
                .like(username != null && !"".equals(username), "username", username)
                .like(nickname != null && !"".equals(nickname), "nickname", nickname)
                .like(phone != null && !"".equals(phone), "phone", phone);
        try {
            QueryListResponseBody<UserItem> res = userService.queryUserList(current, pageSize, queryWrapper);
            return Result.success(res);
        } catch (Exception e) {
            log.warn("Exception", e);
            return Result.error(ResultEnum.DEFAULT_ERROR);
        }
    }

    /**
     * 修改用户密码
     *
     * @param user 当前用户
     * @param req  serRequestBody.ChangePassword
     * @return null
     */
    @PutMapping("/change_password")
    public Result<?> changePassword(@CurrentUser User user,
                                    @Valid @RequestBody UserRequestBody.ChangePassword req) {
        if (!PasswordMD5.getPasswordMD5(req.getOldPassword()).equals(user.getPassword())) {
            return Result.error(ResultEnum.PASSWORD_ERROR);
        }
        try {
            user.setPassword(PasswordMD5.getPasswordMD5(req.getNewPassword()));
            boolean success = userService.updateById(user);
            if (success) {
                return Result.success(null);
            } else {
                log.warn("change password error.");
                return Result.error(ResultEnum.DEFAULT_ERROR);
            }
        } catch (Exception e) {
            log.warn("Exception", e);
            return Result.error(ResultEnum.DEFAULT_ERROR);
        }
    }

    @PostMapping("/forgot_password/auth_code")
    public Result<SmsResponseBody> getAuthCode(@Valid @RequestBody UserRequestBody.GetAuthCode req) {
        /* 先查询是否存在该手机号对应的用户 */
        String phoneNumber = req.getPhoneNumber();
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("phone", phoneNumber);
        User user = userService.getOne(userQueryWrapper);
        if (user == null) {
            return Result.error(ResultEnum.USER_NOT_FOUND);
        }
        /* 生成验证码 */
        StringBuilder authCode = new StringBuilder();
        for (int j = 0; j < zhenziSmsConfig.getLength(); j++) {
            authCode.append(new Random().nextInt(10));
        }
        try {
            SmsResponseBody res = smsService.sendAuthCode(phoneNumber, authCode.toString());
            return Result.success(res);
        } catch (NoBalanceException e) {
            log.warn("NoBalanceException", e);
            return Result.error(ResultEnum.NO_BALANCE_ERROR);
        } catch (Exception e) {
            log.warn("Exception", e);
            return Result.error(ResultEnum.DEFAULT_ERROR);
        }
    }

    @PostMapping("/forgot_password/reset")
    public Result<?> verifyAuthCode(@Valid @RequestBody UserRequestBody.ResetPassword req) {
        try {
            boolean correct = smsService.verifyAuthCode(req.getUuid(), req.getCode());
            if (correct) {
                String uuid = req.getUuid();
                SmsLog smsLog = smsService.getSmsLogByUuid(uuid);
                String phone = smsLog.getPhone();
                QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
                userQueryWrapper.eq("phone", phone);
                User user = userService.getOne(userQueryWrapper);
                user.setPassword(PasswordMD5.getPasswordMD5(req.getNewPassword()));
                userService.updateById(user);
                return Result.success(null);
            } else {
                return Result.error(ResultEnum.DEFAULT_ERROR);
            }
        } catch (AuthCodeExpiredException e) {
            log.warn("AuthCodeExpiredException", e);
            return Result.error(ResultEnum.AUTH_CODE_EXPIRED_ERROR);
        } catch (AuthCodeNotMatchException e) {
            log.warn("AuthCodeNotMatchException", e);
            return Result.error(ResultEnum.AUTH_CODE_ERROR);
        }

    }
}
